package GigabitFpga

import (
	"encoding/json"
	"fmt"
	"math"
	"os"
	"path/filepath"
	"sync"
)

var (
	nbFilters   []CTRL_WORD_DDC
	wbFilters   []CTRL_WORD_DDC
	nbLoaded    bool
	wbLoaded    bool
	filtersOnce sync.Once
)

// 【关键】自定义类型：完美支持 true/false、0/1、"0"/"1" 三种写法
type BoolInt int32

func (b *BoolInt) UnmarshalJSON(data []byte) error {
	if len(data) == 0 {
		*b = 0
		return nil
	}
	switch data[0] {
	case 't', 'T':
		*b = 1
		return nil
	case 'f', 'F':
		*b = 0
		return nil
	}
	var v int32
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	*b = BoolInt(v)
	return nil
}

type CTRL_WORD_DDC struct {
	NInFreq  uint32 `json:"-"`
	NOutFreq uint32 `json:"NCO,omitempty"` // 宽带有，窄带没有

	NCICShiftFactor int32 `json:"-"`
	NCICStage       int32 `json:"-"`
	NCICDecimate    int32 `json:"nCICDECI,omitempty"`

	NFir1Deci uint8 `json:"nFIR1DECI,omitempty"` //下抽倍数
	NFir2Deci uint8 `json:"nFIR2DECI,omitempty"`

	NCoeffFir1   []int16 `json:"nFIR1Coef,omitempty"`
	NCoeffFir2   []int16 `json:"nFIR2Coef,omitempty"`
	NCoeffResamp []int16 `json:"nFIR3Coef,omitempty"`

	NCICBypass      BoolInt `json:"cic_bypass,omitempty"`
	NFir1Bypass     BoolInt `json:"fir1_bypass,omitempty"`     //滤波器1是否启用
	NFir2Bypass     BoolInt `json:"fir2_bypass,omitempty"`     //滤波器2是否启用
	NResampleBypass BoolInt `json:"resample_bypass,omitempty"` //重采样滤波器是否启用

	NRsin1 uint32 `json:"Rsin,omitempty"`
	NRsin2 uint32 `json:"-"`

	NResampleLen int32 `json:"-"` //固定1024阶
}

var iswb bool

// 关键：窄带加载时要根据索引自动填充 NOutFreq
func (c *CTRL_WORD_DDC) setNarrowbandOutFreq(index int) {
	// 原厂窄带从 50kHz 开始，每 1kHz 一条
	c.NOutFreq = 50000 + uint32(index)*1000
}

func (c *CTRL_WORD_DDC) normalize() {
	c.NInFreq = 245760000 // 固定输入采样率，永不改变
	c.NCICStage = 5       // CIC 固定 5 阶
	// 注意：窄带不要依赖 NCO 字段！
}

func (c *CTRL_WORD_DDC) finalize(isWideband bool) {
	c.normalize()
	if isWideband {
		c.NCICShiftFactor = 51 - 16 - int32(math.Floor(5*math.Log2(2*float64(c.NCICDecimate))))
	} else {
		c.NCICShiftFactor = 56 - 16 - int32(math.Floor(5*math.Log2(2*float64(c.NCICDecimate))))
	}

	totalDeci := float64(c.NCICDecimate) * float64(c.NFir1Deci) * float64(c.NFir2Deci)
	c.NRsin1 = uint32(math.Round(math.Pow(2, 32) * 32 / totalDeci))
	c.NRsin2 = uint32(math.Round(float64(c.NOutFreq) * math.Pow(2, 32) / 245760000.0))
}

// 在 NewMtcasdr 最后调用一次即可
func LoadAllFilters() {
	nbFilters = nil
	wbFilters = nil
	nbLoaded = false
	wbLoaded = false
	iswb = true
	filtersOnce.Do(func() {
		loadNBFilter()
		loadWBFilter()
	})
}

// 加载窄带滤波器表（100% 对应 __mtcasdr_read_nbfilter）
func loadNBFilter() {
	path := findFilterFile("nbfilters.filter")
	if path == "" {
		fmt.Println("[mtcasdr] 未找到 nbfilters.filter")
		return
	}

	data, err := os.ReadFile(path)
	if err != nil {
		fmt.Printf("[mtcasdr] 读取窄带滤波器失败: %v\n", err)
		return
	}

	var filters []CTRL_WORD_DDC
	if err := json.Unmarshal(data, &filters); err != nil {
		fmt.Printf("[mtcasdr] 解析窄带滤波器失败: %v\n", err)
		return
	}

	// 关键：窄带要根据索引设置 NOutFreq
	for i := range filters {
		filters[i].setNarrowbandOutFreq(i)
		filters[i].normalize()
	}

	nbFilters = filters
	nbLoaded = true
	fmt.Printf("[mtcasdr] 窄带滤波器加载成功，共 %d 组（50kHz ~ %.3fMHz）\n",
		len(filters), float64(50000+len(filters)*1000-1000)/1e6)
}

// 加载宽带滤波器表（100% 对应 __mtcasdr_read_wbfilter）
func loadWBFilter() {
	path := findFilterFile("wbfilters.filter")
	fmt.Println("wb path:" + path)
	if path == "" {
		fmt.Println("[mtcasdr] 未找到 wbfilters.filter，宽带滤波器未加载")
		return
	}

	filters, err := parseDDCFilterFile(path)
	if err != nil {
		fmt.Printf("[mtcasdr] 加载宽带滤波器失败: %v\n", err)
		return
	}

	wbFilters = filters
	wbLoaded = true
	fmt.Printf("[mtcasdr] 宽带滤波器加载成功，共 %d 组\n", len(filters))
}

func parseDDCFilterFile(path string) ([]CTRL_WORD_DDC, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	var filters []CTRL_WORD_DDC
	if err := json.Unmarshal(data, &filters); err != nil {
		return nil, fmt.Errorf("filter file format error: %v", err)
	}

	for i := range filters {
		filters[i].normalize()
		if iswb {
			fmt.Println(filters[i].NCICShiftFactor)
		}
		// 延迟 finalize，等真正使用时再决定是宽带还是窄带
	}
	return filters, nil
}

func FindNBFilter(bandwidth uint32) (CTRL_WORD_DDC, bool) {
	for _, f := range nbFilters {
		if bandwidth <= f.NOutFreq {
			cfg := f
			cfg.finalize(false) // 窄带
			fmt.Println("find nb success")
			return cfg, true
		}
	}
	return CTRL_WORD_DDC{}, false
}

func FindWBFilter(bandwidth uint32) (CTRL_WORD_DDC, bool) {
	for _, f := range wbFilters {
		if bandwidth == f.NOutFreq {
			cfg := f
			cfg.finalize(true) // 宽带
			fmt.Println("find wb success")
			return cfg, true
		}
	}
	fmt.Println("find wb failed")
	return CTRL_WORD_DDC{}, false
}

// 查找滤波器文件（支持 exe 同目录）
func findFilterFile(name string) string {
	locations := []string{
		name,
		filepath.Join(".", name),
	}
	if exe, err := os.Executable(); err == nil {
		locations = append(locations, filepath.Join(filepath.Dir(exe), name))
	}
	for _, p := range locations {
		if _, err := os.Stat(p); err == nil {
			return p
		}
	}
	return ""
}

// 查询接口（外部调用）
func IsNBFilterLoaded() bool { return nbLoaded }
func IsWBFilterLoaded() bool { return wbLoaded }
func GetNBFilterCount() int  { return len(nbFilters) }
func GetWBFilterCount() int  { return len(wbFilters) }
